/******************************************************************************/
#include "stdafx.h"
#include "Main.h"
/******************************************************************************/
void ChatMessage::draw(TextStyle &ts, Vec2 &box_top_left, Flt box_width, Flt margin)
{
   Rect_LU rect(box_top_left+Vec2(0, -y_min), box_width, height);
   rect.draw(background);
   rect.min.x+=margin;
   D.text(ts, rect, text, AUTO_LINE_SPACE);
}
/******************************************************************************/
ChatMessages& ChatMessages::create()
{
   super::create();

   margin=0.01;

   ts.reset();
   ts.scale=0.05;
   ts.align.set(1,-1);

   return T;
}
/******************************************************************************/
void ChatMessages::New(Str text)
{
   Bool    at_end=false;
   Region *region=NULL;
   if(parent() && parent()->type()==GO_REGION)
   {
      region=&parent()->asRegion();
      SlideBar &sb=region->slidebar[1];
      if(sb.offsetDesired()+sb.length()>=sb.lengthTotal()-0.02f)at_end=true;
   }

   Int index=messages.elms();
   messages.New().set(text, index);

   for(;messages.elms()>100;)messages.remove(0, true); // allow only up to 100 messages

   rebuildSpace();

   if(at_end)region->scrollY(9999); // auto-scroll
}
/******************************************************************************/
void ChatMessages::rebuildSpace()
{
   Flt y=0, width=0;

   Region *region=NULL;
   if(parent() && parent()->type()==GO_REGION)region=&parent()->asRegion();

   if(region)width=region->crect.w()-margin;

   FREPA(messages)
   {
      Flt h=Max(1, ts.textLines(messages[i].text, width, AUTO_LINE_SPACE))*0.05f;

      messages[i].height=h  ;
      messages[i].y_min =y  ;
      messages[i].y_max =y+h;

      y+=h;
   }
   
   if(region)region->setSize(&Vec2(0,y));
}
/******************************************************************************/
static Int FindMinY(C ChatMessage &message, C Flt &min_y) {return Compare(message.y_max, min_y);}
static Int FindMaxY(C ChatMessage &message, C Flt &max_y) {return Compare(message.y_min, max_y);}

void ChatMessages::draw(C GuiPC &gpc)
{
   if(visible() && !gpc.hidden && parent() && parent()->type()==GO_REGION)
   {
      // clip drawing rectangle
      D.clip(gpc.clip);

      // calculate offsets
      Region &region       =parent()->asRegion();
      Flt     offset       =region.slidebar[1].offset(); // get region's vertical slidebar offset
      Vec2    box_top_left =gpc.offset;                  // get top left corner in "screen space"
      Flt     box_width    =region.crect.w(),            // get visible space width
              visible_min_y=offset,                      // get visible space in "message space"
              visible_max_y=region.crect.h()+offset;     // get visible space in "message space"

      // find visible message indexes
      Int from, to;
      messages.binarySearch(visible_min_y, from, FindMinY),
      messages.binarySearch(visible_max_y, to  , FindMaxY);

      // draw them
      for(Int i=from; i<to; i++)messages[i].draw(ts, box_top_left, box_width, margin);
   }
}
/******************************************************************************/
